TS-02 接口定义、函数定义
一、接口
接口为类型接口,提供给变量使用类型的;
- 生成
tslint.json
文件:tslint --init
- 配置
tslint
文件
json
"rules": {
"quotemark": false, // 取消双引号
"semicolon": false, // 取消结尾分号
"interface-name": [true, "never-prefix"], //interface接口不需要前缀
"object-listeral-sort-keys": false, // 接口排序不按照首字母排序
}
使用interface来定义接口
定义接口使用逗号隔开、分号隔开、换行都是可以的;
js
// 对象定义接口
interface Vegetable {
color?: string, // 可选属性
type: string, // 必填属性
}
const getVegetable = ({color, type}: Vegetable): string => {
return `${color ? (color + ' ') : ''}${type}`
}
// 数组定义接口
interface ArrInter {
0: string,
1: number
}
let arr: ArrInter = ['a',2]
任意属性
- 使用类型断言
ts
getVegetable({
color: 'red',
type: 'tomato',
size: 2
} as Vegetable) // 类型断言, 指定就是Vegetable
- 使用
[propName: string]
ts
interface Vegetable {
color?: string,
type: string,
[prop: string]: any // 索引只能是string或number 属性是字符串, 值是任意类型
}
注意:如果值不是any,而是string或number,则成员都得是string或number,当然也可以使用或者;
- 提取对象
ts
const vegetableInfo = {
color: 'red',
type: 'tomato',
size: 2
}
getVegetable(vegetableInfo) // 将对象取出存变量, 里面的属性多了无所谓
只读属性
js
interface Vegetable {
color?: string,
readonly type: string // 只读的, 无法被修改
}
let obj: Vegetable = {type: 'tomato'}
obj.type = 'carrot' // 报错
定义函数
js
interface AddFun {
(num1: number, num2: number): number
}
//使用
const add: AddFun = (n1, n2) => n1 + n2
索引类型 使用接口定义数组
js
interface RoleDic {
[index: number]: string
}
const role: RoleDic = {
0: 'admin' // 只能是数字类型的属性名, 否则报错
}
// 当指定的索引类型为string时
interface RoleDic {
[id: string]: string
}
const role: RoleDic = {
0: 'admin' // 数字也不会报错, 因为属性名会被调用toString转换
}
接口继承
js
interface Vegetable {
color: string
}
interface Tomato extends Vegetable {
radius: number
}
// Tomato接口继承了Vegetable接口, 在使用时必须传入两个参数, color和radius;
混合类型
ts3.1之前的版本需要借助命名空间,ts3.1之后的版本可以直接定义接口混合类型
js
interface Counter {
(): void, // 返回空的函数
count: number // 给函数添加count属性
}
// 返回的类型就是Counter,有一个函数和一个属性
const getCounter = (): Counter => {
const c = () => {c.count++}
c.count = 0
return c
}
// 接收的类型就是Counter, 有函数和属性
const counter: Counter = getCounter()
总结
- 定义接口
js
interface Person {
name: string,
age?: number,
readonly size: number, // 只读属性
[prop: string]: any // 多余属性要写any
}
- 索引类型,当为string时,可以是数字和字符串,当为number时,只能是数字
- 当参数传入过多时,解决办法
- 解决一:定义[prop:string]: any
- 解决二:使用类型断言,强行指定类型
- 解决三:定义一个变量,传入方法
- 接口继承:使用
extends
,和类相似 - 混合类型:在一个函数上面即有属性也有方法
二、函数
函数声明
ts
// 函数声明
function sum(x, y){
return x + y
}
// 函数表达式
let mySum = function(x,y){
return x + y
}
函数声明定义类型
- 函数声明需要把输入和输出都考虑到
ts
function sum(x: number, y:number): number{
return x + y
}
sum(1,2,3) // 多余参数报错
函数表达式
ts
// 错误的函数表达式声明
let add = function(x: number, y:number): number => {
return arg1 + arg2
}
// 错误的声明方式add是通过类型推论出来的,下面的是正确的声明类型;
// 正确的类型声明
let add: (x:number, y: number) => number = (arg1: number, arg2: number): number => {
return arg1 + arg2
}
let add: (x:number, y: number) => number
add = (arg1: string, arg2: number) => arg1 + arg2 // 会报错, arg1不能为string
let arg3;
add = (arg1: number, arg2: number) => arg1 + arg2 + arg3 // arg3是不需要写在参数里面的
类型别名定义函数
类型别名使用type定义
ts
// 使用别名定义函数
type Add = (x: number, y: number) => number
type isString = string // isString就是string了
可选参数
在js中,可选参数可以是在任何地方,只要使用undefined占位;
在ts中,可选参数必须是在最后面;
js
type AddFunction = (arg1: number, arg2: number, arg3?: number) => number
let addF: AddFunction
addF = (arg1:number, arg2: number) => arg1 + arg2
默认值
在定义默认值可以不需要类型判断, 因为会自动判断类型, 在传入时也不能传入字符串了
js
addF = (arg1: number, arg2 = 3) => arg1 + arg2
不确定形参个数
args为数组,因此后面的类型使用数组判断,使用...接收剩余的参数
js
const handleData = (arg1: number, ...args: number[]) => {}
函数重载
重载允许一个函数接受不同数量或类型的参数时,作不同的处理;
函数重载只能使用function来定义,不能使用接口和类型别名定义;
js
// 函数之前定义方法
function reverse(x: number | string): number[] | string[] {}
// 有一个缺点, 不能够精确的表达;
// 函数重载
function reverse(x: number): number[]
function reverse(x: string): string[]
function reverse(x: any): any {
if(typeof x === 'string'){
return x.split('')
} else {
return x.toString().split('').map((item) => Number(item))
}
}